########################################################################
#  Searx-qt - Lightweight desktop application for SearX.
#  Copyright (C) 2020  CYBERDEViL
#
#  This file is part of Searx-qt.
#
#  Searx-qt is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Searx-qt is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################

from PyQt5.QtWidgets import (
    QToolButton,
    QFrame,
    QHBoxLayout,
    QLabel,
    QMenu,
    QWidgetAction,
    QCheckBox
)

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor


class Button(QToolButton):
    """ QToolButton with option to set text at creation.
    """
    def __init__(self, text="", parent=None):
        QToolButton.__init__(self, parent=parent)
        self.setText(text)


class CheckboxOptionsButton(QFrame):
    def __init__(self, labelName="", parent=None):
        QFrame.__init__(self, parent=parent)

        layout = QHBoxLayout(self)
        layout.setContentsMargins(3, 3, 3, 3)

        self._labelName = labelName

        self.setFrameShape(QFrame.StyledPanel)

        openButton = Button("+", self)
        layout.addWidget(openButton, 0, Qt.AlignLeft | Qt.AlignTop)

        self._label = QLabel("", self)
        self._label.setWordWrap(True)
        layout.addWidget(self._label, 1, Qt.AlignLeft | Qt.AlignTop)

        openButton.clicked.connect(self.__toggleMenu)

        self.__genLabel()

    @property
    def labelName(self):
        return self._labelName

    @labelName.setter
    def labelName(self, name):
        self._labelName = name

    def __genLabel(self):
        str_ = ""
        for key, name, state in self.getOptions():
            if state:
                if str_:
                    str_ += ", "
                str_ += name

        if not str_:
            str_ = "All"

        self._label.setText("<b>" + self._labelName + "</b>: " + str_)
        self._label.setToolTip(str_)

    def __addWidgets(self, menu):
        for key, name, state in self.getOptions():
            action = QWidgetAction(menu)
            widget = QCheckBox(name, menu)
            widget.setTristate(False)
            widget.setChecked(state)
            action.setDefaultWidget(widget)

            widget.stateChanged.connect(
                lambda state, key=key:
                    self.__checkBoxStateChanged(key, state)
            )

            menu.addAction(action)

    def __toggleMenu(self):
        menu = QMenu(self)
        menu.setStyleSheet("QMenu { menu-scrollable: 1; }")
        self.__addWidgets(menu)
        menu.exec(QCursor.pos())

    def __checkBoxStateChanged(self, key, state):
        self.optionToggled(key, state == 2)
        self.__genLabel()

    """ Methods below should be reimplemented.
    """

    def getCheckedOptionNames(self):
        """ Should return a list with checked option names.

        @return: should return a list with strings.
        @rtype: list
        """
        # Re-implement this!
        return []

    def getOptions(self):
        """ Should return a list with options tuple(key, name, state)

        This will be used to generate the options.
        """
        # Re-implement this!
        list_ = []
        for key, t in self._searchModel.categories.types.items():
            state = self._searchModel.categories.get(key)
            list_.append((key, t[0], state))

        return list_

    def optionToggled(self, key, state):
        # Re-implement to do stuff here.
        return
